<script setup>
import { Close } from '@element-plus/icons-vue'
import { getMsgFileURL, inspectClientFile, previewImg } from '@/assets/api/message'
import useEventBus from '@/use/use-event-bus'
import useChannel from '@/store/channel'
import { transformFileSize } from '@/utils'

const props = defineProps({
  file: Object,
  download: Boolean,
  delete: Boolean,
  loading: Boolean,
  adaptive: Boolean,
})
const emit = defineEmits(['deleteFile'])
const suffix = fileSuffix(props.file)
const isImg = ['jpg', 'png', 'jpeg'].includes(suffix)
const eventBus = useEventBus()
const channelStore = useChannel()

const imgUrl = ref(null)

watch(
  () => props.file,
  () => {
    if (isImg) {
      if (props.file.id) {
        previewImg(props.file.id).then((res) => {
          if (res.code === 500) {
            // TODO 图片丢失了
          } else {
            imgUrl.value = window.URL.createObjectURL(res)
            eventBus.emit('setUrlList', imgUrl.value)
          }
        })
      } else {
        const target = props.file.uuid ? props.file.file : props.file
        if (target) {
          imgUrl.value = window.URL.createObjectURL(target)
          eventBus.emit('setUrlList', imgUrl.value)
        }
        // 文件如果不存在的话，两秒后去查询
        else {
          const stop = setTimeout(() => {
            inspectClientFile(props.file.uuid).then((res) => {
              if (res.code === 200) {
                channelStore.updateFileStatus(res.data)
              }
            })
          }, 2000)
          eventBus.on('stopInspectClientFile', (uuid) => {
            if (uuid === props.file.uuid) {
              stop && stop()
            }
          })
        }
      }
    }
  },
  {
    deep: true,
    immediate: true,
  }
)

const info = computed(() => {
  let type = ''
  let color = ''
  if (['xlsx'].includes(suffix)) {
    type = 'excel'
    color = 'rgb(16, 124, 65)'
  } else if (['docx'].includes(suffix)) {
    type = 'word'
    color = 'rgb(24, 90, 189)'
  }
  return {
    name: `file-${type}`,
    color,
  }
})

// 文件类型
function fileSuffix(file) {
  return file?.name.split('.').pop() || ''
}

function fileType({ extension }) {
  if (['xlsx', 'xls'].includes(extension)) {
    return 'excel'
  }
  if (['doc', 'docx'].includes(extension)) {
    return 'word'
  }
  if (['ppt', 'pptx'].includes(extension)) {
    return 'ppt'
  }
  if (['png', 'jpg', 'jpeg', 'gif'].includes(extension)) {
    return 'img'
  }
  if (['mp4', 'mov'].includes(extension)) {
    return 'video'
  }
  if (['mp3'].includes(extension)) {
    return 'music'
  }
  if (['zip', 'rar', '7z'].includes(extension)) {
    return 'zip'
  }
  if (extension === 'folder') {
    return 'folder'
  }
  return 'default'
}

const downloadLoading = ref(false)
const downloadProgress = ref(0)

async function downloadFile() {
  const link = document.createElement('a')
  if (props.file.id) {
    downloadLoading.value = true
    const buffer = await getMsgFileURL(props.file.id, 'download', (e) => {
      downloadProgress.value = e.progress
    })
    downloadLoading.value = false
    downloadProgress.value = 0
    link.href = URL.createObjectURL(new Blob([buffer]))
  } else {
    link.href = URL.createObjectURL(props.file.file)
  }
  link.download = props.file.name
  link.style.display = 'none'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(link.href)
}
</script>

<template>
  <div v-if="isImg" class="file-card file-card-image" :class="{ 'img-adaptive': props.adaptive && isImg }">
    <img :src="imgUrl" alt="" @click="eventBus.emit('viewImg', imgUrl)" loading="lazy" />
    <div v-if="props.delete" class="file-delete" @click="emit('deleteFile', props.file)">
      <el-icon><Close /></el-icon>
    </div>
  </div>
  <div v-else class="file-card">
    <div class="file-card-content">
      <div class="file-icon">
        <SvgIcon
          v-bind="info"
          size="40"
          :name="props.file.extension === 'folder' ? 'folder' : `file-${fileType(props.file)}`"></SvgIcon>
      </div>
      <div class="file-info">
        <div class="file-name">
          <span>{{ props.file.name }}</span>
        </div>
        <div class="file-size">{{ suffix }} {{ transformFileSize(props.file.size) }}</div>
      </div>
      <div v-if="props.delete" class="file-delete" @click.stop="emit('deleteFile', props.file)">
        <el-icon><Close /></el-icon>
      </div>
    </div>
    <div v-if="!props.delete" class="file-card-thumbnail">
      <SvgIcon
        v-bind="info"
        size="65"
        :name="props.file.extension === 'folder' ? 'folder' : `file-${fileType(props.file)}`"></SvgIcon>
    </div>
    <div v-if="props.download" class="operation">
      <div class="operation-btn" @click="!downloadLoading && downloadFile()">
        下载
        <span v-if="downloadLoading">({{ `${Math.round(downloadProgress * 100)}%` }})</span>
      </div>
    </div>
    <div v-if="loading" class="file-progress">{{ Math.round(props.file.progress * 100) }}%</div>
  </div>
</template>

<style scoped lang="scss">
.file-card {
  cursor: pointer;
  position: relative;
  width: 350px;
  border-radius: 5px;
  &:not(:last-child) {
    margin-right: 10px;
    margin-bottom: 10px;
  }
  .file-card-content {
    @include use-flex();
    .file-icon {
      width: 40px;
      height: 40px;
    }
    .file-info {
      width: calc(100% - 40px);
      padding-left: 5px;
      .file-name {
        font-size: 14px;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        word-break: break-all;
      }
      .file-size {
        font-size: 13px;
        color: var(--elp-text-color-secondary);
      }
    }
  }
  .file-card-thumbnail {
    @include use-flex(center, center);
    height: 190px;
    margin-top: 10px;
    border-radius: var(--elp-border-radius-base);
    background-color: var(--elp-bg-color);
  }
  .file-progress {
    @include use-flex(center, center);
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    color: var(--elp-color-primary);
    background-color: var(--elp-mask-color);
  }
  .operation {
    display: flex;
    justify-content: space-between;
    margin-top: 10px;
    .operation-btn {
      flex: 1;
      text-align: center;
      border: var(--elp-border);
      padding: 5px;
      border-radius: var(--elp-boder-radius-small);
      cursor: pointer;
      background-color: var(--elp-bg-color);
      &:hover {
        background-color: var(--elp-color-info-light-8);
      }
      & + .operation-btn {
        margin-left: 10px;
      }
    }
  }
}
.file-card-image {
  width: 52px;
  max-width: 300px;
  img {
    width: 100%;
  }
}
.file-delete {
  position: absolute;
  right: 5px;
  top: 5px;
}
.img-adaptive {
  height: auto;
  width: auto;
}
</style>
